package org.budo.redis.repository.util;

import org.budo.redis.repository.jedis.graph.BudoRedisGraphService;
import org.budo.redis.repository.jedis.graph.BudoRedisGraphServiceImpl;
import org.budo.redis.repository.spring.data.graph.BudoSpringDataRedisGraphService;
import org.budo.redis.repository.spring.data.graph.BudoSpringDataRedisGraphServiceImpl;
import org.budo.support.spring.context.aware.BudoApplicationContextAware;
import org.budo.support.spring.util.SpringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

/**
 * @author lmw
 */
public class BudoRedisGraphUtil {
    private static final Logger log = LoggerFactory.getLogger(BudoRedisGraphUtil.class);

    private static BudoRedisGraphService _redisGraphService = null;

    private static BudoSpringDataRedisGraphService _springDataRedisGraphService = null;

    public static BudoSpringDataRedisGraphService springDataRedisGraph() {
        if (null != _springDataRedisGraphService) {
            return _springDataRedisGraphService;
        }

        synchronized (BudoRedisGraphUtil.class) {
            if (null != _springDataRedisGraphService) {
                return _springDataRedisGraphService;
            }

            if (null == BudoApplicationContextAware.getInstance()) {
                return BudoSpringDataRedisGraphServiceImpl.INSTANCE;
            }

            return _springDataRedisGraphService = _findSpringDataRedisGraphService();
        }
    }

    public static BudoRedisGraphService redisGraph() {
        if (null != _redisGraphService) {
            return _redisGraphService;
        }

        synchronized (BudoRedisGraphUtil.class) {
            if (null != _redisGraphService) {
                return _redisGraphService;
            }

            if (null == BudoApplicationContextAware.getInstance()) {
                return BudoRedisGraphServiceImpl.INSTANCE;
            }

            return _redisGraphService = _findBudoRedisGraphService();
        }
    }

    private static BudoSpringDataRedisGraphService _findSpringDataRedisGraphService() {
        BudoApplicationContextAware applicationContextAware = BudoApplicationContextAware.getInstanceNoNull();
        ApplicationContext applicationContext = applicationContextAware.getApplicationContext();
        if (null == applicationContext) {
            log.error("#63 applicationContext is null, applicationContextAware=" + applicationContextAware);
            return new BudoSpringDataRedisGraphServiceImpl();
        }

        BudoSpringDataRedisGraphService graphService = SpringUtil.getBean(applicationContext, BudoSpringDataRedisGraphService.class);
        if (null != graphService) {
            log.info("#69 BudoRedisGraphService in applicationContext found, graphService=" + graphService);
            _springDataRedisGraphService = graphService;
            return graphService;
        }

        log.error("#74 _redisGraphService not found, new TaojinRedisGraphServiceImpl()");
        return new BudoSpringDataRedisGraphServiceImpl();
    }

    private static BudoRedisGraphService _findBudoRedisGraphService() {
        BudoApplicationContextAware applicationContextAware = BudoApplicationContextAware.getInstanceNoNull();
        ApplicationContext applicationContext = applicationContextAware.getApplicationContext();
        if (null == applicationContext) {
            log.error("#23 applicationContext is null, applicationContextAware=" + applicationContextAware);
            return new BudoRedisGraphServiceImpl();
        }

        BudoRedisGraphService graphService = SpringUtil.getBean(applicationContext, BudoRedisGraphService.class);
        if (null != graphService) {
            log.info("#36 BudoRedisGraphService in applicationContext found, graphService=" + graphService);
            _redisGraphService = graphService;
            return graphService;
        }

        log.error("#41 _redisGraphService not found, new TaojinRedisGraphServiceImpl()");
        return new BudoRedisGraphServiceImpl();
    }
}